package app.auto.runner.base.intf;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import app.auto.annotation.Show;

/**
 * Created by admin on 2017/3/2.
 */
public class ListBuilder<T> {
    MapBuilder mapBuilder;
    private MapBuilder trans;
    private ListBuilder listHolder;

    public MapBuilder newMapBuilder() {
        return getMapBuilderPrivate();
    }

    private MapBuilder getMapBuilderPrivate() {
        mapBuilder = MapBuilder.build();
        mapBuilder.setListBuilder(this);
        list.add((T) mapBuilder.get());
        return mapBuilder;
    }


    public static Map search(List list, String name, Object value) {
        for (Object o : list) {
            if (value.toString().equals(((Map) o).get(name).toString())) {
                return ((Map) o);
            }

        }
        return null;
    }

    public static ListBuilder with(List list) {
        ListBuilder lb = build();
        lb.list = list;
        return lb;
    }

    public ListBuilder addAll(List list) {
        this.list.addAll(list);
        return this;
    }


    public List<T> list = new ArrayList();

    public static ListBuilder build() {
        return new ListBuilder();
    }

    public static void transfer(List obj, Setter setter) {
        for (Object o : obj) {
            for (Object p : setter.getParams()) {
                setter.onCallback(p.toString(), ((Map) o));
            }

        }
    }

    //    public List list(String word) {
//        for (Object o : get()) {
//            if (o != null) {
//                if (o.toString().equals("")) {
//
//                }else {
//
//                }
//
//            }
//        }
//    }
    @Show
    public ListBuilder add(T v) {
        if (v == null || v.toString().equals("null")) {

        } else {
            list.add(v);
        }
        return this;
    }

    @Show
    public ListBuilder addRaw(T v) {

            list.add(v);
        return this;
    }
    @Show
    public List<T> get() {
        if (trans != null) {
            list = getResult();
        }
        return list;
    }

    public ListBuilder setTransOption(MapBuilder trans) {
        this.trans = trans;
        return this;
    }

    public List getResult() {
        return getResult(list);
    }


    public List getResult(List arrayList) {

        int i = -1;
        List rt = new ArrayList();
        for (Object o : arrayList) {
            i++;
            if (o instanceof Map) {

                Map rd = ((Map) o);
                Object newo;
                try {
                    newo = trans.getClz().newInstance();

                    for (Object k : trans.get().keySet()) {
                        String mapname = k.toString();
                        Object value = rd.get(mapname);

                        if (mapname.equals("$self")) {
                            value = MapBuilder.build().addMap(rd).get();
                        } else if (mapname.equals("$index")) {
                            value = i + "";
                        }
                        String objectname = (String) trans.get().get(mapname);

                        Field f;
                        f = trans.getClz().getField(objectname);

                        if (f == null) {
                            f = trans.getClz().getDeclaredField(objectname);
                        }
                        if (f == null) {
                            continue;
                        }
                        f.set(newo, value);
                    }
                    rt.add(newo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (rt.size() == 0) {
            rt.addAll(arrayList);
        }
        return rt;

    }

    public ListBuilder newListBuilder() {
        listHolder = ListBuilder.build();
        listHolder.setParentBuilder(this);
        list.add((T) listHolder.get());
        return listHolder;
    }


    private ListBuilder parentBuilder;

    public void setParentBuilder(ListBuilder listBuilder) {
        this.parentBuilder = listBuilder;
    }

    public ListBuilder getListHolder() {
        return listHolder;
    }

    public ListBuilder addMapBuilderData(String s, Object s1) {
        if (list == null) {
            return build().getMapBuilderPrivate().add(s, s1).getListHolder();
        } else {
            return getMapBuilderPrivate().add(s, s1).getListHolder();

        }
    }
}
